﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using CommonLib;

namespace TrackingClient
{
    public partial class frmTrackingClient : Form
    {
        // Will hold the user name
        private string UserName = "Unknown";
        private StreamWriter swSender;
        private StreamReader srReceiver;
        private TcpClient tcpServer;
        // Needed to update the form with messages from another thread
        private delegate void UpdateLogCallback(string strMessage);
        // Needed to set the form to a "disconnected" state from another thread
        private delegate void CloseConnectionCallback(string strReason);
        private Thread thrMessaging;
        private IPAddress ipAddr;
        private bool Connected;

        public frmTrackingClient()
        {
            // On application exit, don't forget to disconnect first
            Application.ApplicationExit += new EventHandler(OnApplicationExit);
            InitializeComponent();
        }

        // The event handler for application exit
        public void OnApplicationExit(object sender, EventArgs e)
        {
            if (Connected == true)
            {
                // Closes the connections, streams, etc.
                //Connected = false;
                //swSender.Close();
                //srReceiver.Close();
                //tcpServer.Close();

                Connected = false;
                thrMessaging.Abort();
                srReceiver.Close();
                swSender.Close();
                tcpServer.Close();
            }
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            
            // If we are not currently connected but awaiting to connect
            if (Connected == false)
            {
                // Initialize the connection
                InitializeConnection();
            }
            else // We are connected, thus disconnect
            {
                CloseConnection("Disconnected at user's request.");
            }
        }

        private void InitializeConnection()
        {
            // Parse the IP address from the TextBox into an IPAddress object
            ipAddr = IPAddress.Parse(txtIp.Text);
            // Start a new TCP connections to the chat server
            tcpServer = new TcpClient();
            tcpServer.Connect(ipAddr, int.Parse(txtPort.Text));

            // Helps us track whether we're connected or not
            Connected = true;
            // Prepare the form
            UserName = txtUser.Text;

            // Disable and enable the appropriate fields
            txtIp.Enabled = false;
            txtUser.Enabled = false;
            txtMessage.Enabled = true;
            btnSend.Enabled = true;
            btnConnect.Text = "Disconnect";

            // Send the desired username to the server
            swSender = new StreamWriter(tcpServer.GetStream());
            swSender.WriteLine(txtUser.Text);
            swSender.Flush();

            // Start the thread for receiving messages and further communication
            thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
            thrMessaging.Start();
        }

        private void ReceiveMessages()
        {
            // Receive the response from the server
            srReceiver = new StreamReader(tcpServer.GetStream());
            // If the first character of the response is 1, connection was successful
            string ConResponse = srReceiver.ReadLine();
            // If the first character is a 1, connection was successful
            if (ConResponse[0] == '1')
            {
                // Update the form to tell it we are now connected
                this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { "Connected Successfully!" });
            }
            else // If the first character is not a 1 (probably a 0), the connection was unsuccessful
            {
                string Reason = "Not Connected: ";
                // Extract the reason out of the response message. The reason starts at the 3rd character
                Reason += ConResponse.Substring(2, ConResponse.Length - 2);
                // Update the form with the reason why we couldn't connect
                this.Invoke(new CloseConnectionCallback(this.CloseConnection), new object[] { Reason });
                // Exit the method
                return;
            }
            // While we are successfully connected, read incoming lines from the server
            while (Connected)
            {
                // Show the messages in the log TextBox
                this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { srReceiver.ReadLine() });
            }
        }

        // This method is called from a different thread in order to update the log TextBox
        private void UpdateLog(string strMessage)
        {
            // Append text also scrolls the TextBox to the bottom each time
            txtLog.AppendText(strMessage + "\r\n");
        }

        // Closes a current connection
        private void CloseConnection(string Reason)
        {
            // Show the reason why the connection is ending
            txtLog.AppendText(Reason + "\r\n");
            // Enable and disable the appropriate controls on the form
            txtIp.Enabled = true;
            txtUser.Enabled = true;
            txtMessage.Enabled = false;
            btnSend.Enabled = false;
            btnConnect.Text = "Connect";

            // Close the objects
            //Connected = false;
            //swSender.Close();
            //srReceiver.Close();
            //tcpServer.Close();

            Connected = false;
            thrMessaging.Abort();
            srReceiver.Close();
            swSender.Close();
            tcpServer.Close();
        }

        // Sends the message typed in to the server
        private void SendMessage()
        {
            if (txtMessage.Lines.Length >= 1)
            {
                swSender.WriteLine(txtMessage.Text);
                swSender.Flush();
                txtMessage.Lines = null;
            }
            txtMessage.Text = "";
        }

        // We want to send the message when the Send button is clicked
        private void btnSend_Click(object sender, EventArgs e)
        {
            //SendMessage();

        }

        private void t1_Tick(object sender, EventArgs e)
        {
            swSender.WriteLine(System.DateTime.Now.TimeOfDay.ToString());
            swSender.Flush();
        }

        // But we also want to send the message once Enter is pressed
        private void txtMessage_KeyPress(object sender, KeyPressEventArgs e)
        {
            // If the key is Enter
            if (e.KeyChar == (char)13)
            {
                SendMessage();
            }
        }

        private void btnAutoSend_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Timer t1 = new System.Windows.Forms.Timer();
            t1.Interval = 5000;
            t1.Tick += new EventHandler(t1_Tick);
            t1.Start();
        }

        //private byte[] CreateLoginPacket()
        //{
        //    PacketProtocol objPacket = new PacketProtocol();

        //    // header for packet from tracking unit to server
        //    objPacket._header = BitConverter.GetBytes((ushort)enumHeader.FromTracking);//new byte[] { 0x24, 0x24 };

        //    //id in hex code: 13612345678, unused bytes is 'f' or '0xff'
        //    objPacket._id = new byte[] { 0x13, 0x61, 0x23, 0x45, 0x67, 0x8f, 0xff };

        //    //command Tradker's login: 0x5000
        //    objPacket._command = BitConverter.GetBytes((ushort)enumCommand.Tracker_Login); ; // new byte[] { 0x00, 0x50 };

        //    //create data
        //    char[] username = new char[20]; //char[20]: 20 bytes
        //    string name = "hgtuan2003";
        //    name.ToCharArray().CopyTo(username, 0);
        //    char[] password = new char[20];
        //    string pass = "123456";
        //    pass.ToCharArray().CopyTo(password, 0);
        //    byte[] data = Encoding.ASCII.GetBytes(string.Format("{0};{1}", username, password));
        //    data.CopyTo(objPacket._data, 0);
            
        //    byte[] packet = objPacket.CreateFullPacket();
        //    return packet;
        //}

        //private byte[] CreateTrackingPacket()
        //{
        //    PacketProtocol objPacket = new PacketProtocol();

        //    // header for packet from tracking unit to server
        //    objPacket._header = BitConverter.GetBytes((Int16)enumHeader.FromTracking);//new byte[] { 0x24, 0x24 };

        //    //id in hex code: 13612345678, unused bytes is 'f' or '0xff'
        //    objPacket._id = new byte[] { 0x13, 0x61, 0x23, 0x45, 0x67, 0x8f, 0xff };

        //    //command Tradker's login: 0x5000
        //    objPacket._command = BitConverter.GetBytes((Int16)enumCommand.Tracker_Login); ; // new byte[] { 0x00, 0x50 };

        //    Tracking objTracking = new Tracking(123, DateTime.Now,
        //        (decimal)10.827911, (decimal)106.627808, 100, 180, "Đông Hưng Thuận, Quận 12", 90, 200, 
        //        true, true, true, true, 90);

        //    byte[] data = objTracking.ConvertObjectToByteArray();
        //    objPacket._data = new byte[data.Length];
        //    data.CopyTo(objPacket._data, 0);

        //    byte[] packet = objPacket.CreateFullPacket();
        //    return packet;
        //}


        private void btnSendProtocol_Click(object sender, EventArgs e)
        {
            Tracking objTracking = new Tracking(123, DateTime.Now,
                (decimal)10.827911, (decimal)106.627808, 100, 180, "Đông Hưng Thuận, Quận 12", 90, 200, 
                true, true, true, true, 90);
            byte[] data = objTracking.ConvertObjectToByteArray();

            PacketProtocol objPacket = new PacketProtocol();
            byte[] packet = objPacket.CreateSendingProtocol(data); //CreatePacket();
            
            ASCIIEncoding encoder = new ASCIIEncoding();
            string buffer = encoder.GetString(packet);

            swSender.Write(buffer);
            swSender.Flush();
        }
    }

    
}